#ifndef STRING_H_
#define STRING_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "types.h"
#include "util.h"

typedef enum _string_cmp {
	CMP_LESS = -1,
	CMP_EQUAL = 0,
	CMP_GREATER = 1,
} s_string_compare;

static inline s_int utf8Skip( s_char code ) {
	if( ( code >> 5 ) == 0x6 ) {
		return 2;
	} else if( ( code >> 4 ) == 0xE ) {
		return 3;
	} else if( ( code >> 3 ) == 0x1E ) {
		return 4;
	} else {
		return 1;
	}
}

s_string* createString();

s_string* createStringA( const char* str );

s_string* createStringW( const wchar_t* str );

s_string* createStringC( const s_char* str );

s_string* createStringCopy( const s_string* str );

void deleteString( s_string* str );

s_uint getStringLengthInBytes( const s_string* str );

s_uint getStringLength( const s_string* str );

s_string_compare compareString( const s_string* str1, const s_string* str2 );

s_string_compare compareStringIgnoreCase( const s_string* str1, const s_string* str2 );

s_string_compare compareStringCharacters( const s_string* str, s_uint start, s_uint end );

s_string_compare compareStringCharactersIgnoreCase( const s_string* str, s_uint count );

s_boolean isStringEqual( const s_string* str1, const s_string* str2 );

s_boolean isStringEqualIgnoreCase( const s_string* str1, const s_string* str2 );

s_boolean isStringEmpty( const s_string str );

s_char charAt( const s_string* str, s_uint at );

s_string* subString( const s_string* str, s_uint start, s_uint end );

s_string* toUpperCase( const s_string* str );

s_string* toLowerCase( const s_string* str );

s_string* concatString( const s_string* src, const s_string* str );	//return src + str

s_string* concatStringCharacters( const s_string* src, const s_string* str, s_uint start, s_uint end );

s_string* preConcatString( const s_string* src, const s_string* str );

s_string* preConcatStringCharacters( const s_string* src, const s_string* str, s_uint start, s_uint end );

s_int findFirstCharacter( const s_string* str, s_char ch );	//-1 not found

s_int findLastCharacter( const s_string* str, s_char ch );

s_int* findAllCharacters( const s_string* str, s_char ch );

s_int findFirstString( const s_string* str1, const s_string* str2 );

s_int findLastString( const s_string* str1, const s_string* str2 );

s_int* findAllStrings( const s_string* str1, const s_string* str2 );

s_string** splitString( const s_string* str, const s_string* delim );

s_string** splitStringCharacter( const s_string* str, s_char delim );

s_string* joinString( const s_string** strs, const s_string* sep );

s_string* joinStringCharacter( const s_string** strs, s_char sep );

s_string* replaceCharacter( const s_string* str, s_char find, s_char replace );

s_string* replaceString( const s_string* str, const s_string* find, const s_string* replace );

s_string* removeCharacter( const s_string* str, s_char remove );

s_string* removeString( const s_string* str, const s_string* remove );

s_string* byteAsString( s_byte n );

s_string* shortAsString( s_short n );

s_string* intAsString( s_int n );

s_string* longAsString( s_long n );

s_string* floatAsString( s_float n );

s_string* doubleAsString( s_double n );

char* asCString( const s_string* str );

wchar_t* asCWString( const s_string* str );

void printStringInfo( const s_string* str );

#endif /*STRING_H_*/
